# Load packages
Warning messages:
1: In readChar(file, size, TRUE) : truncating string with embedded nuls
2: In readChar(file, size, TRUE) : truncating string with embedded nuls
3: In readChar(file, size, TRUE) : truncating string with embedded nuls
4: In readChar(file, size, TRUE) : truncating string with embedded nuls
5: In readChar(file, size, TRUE) : truncating string with embedded nuls
6: In readChar(file, size, TRUE) : truncating string with embedded nuls
7: In readChar(file, size, TRUE) : truncating string with embedded nuls
8: In readChar(file, size, TRUE) : truncating string with embedded nuls
library(ggplot2)
library(dplyr)
library(tidyr)
library(tidyverse)
library(plotly)
str(coronavirus)
tibble [157,000 × 8] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ ID      : int [1:157000] 1 2 3 4 5 6 7 8 9 10 ...
 $ date    : Date[1:157000], format: "2020-01-22" "2020-01-23" ...
 $ province: logi [1:157000] NA NA NA NA NA NA ...
 $ country : chr [1:157000] "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ...
 $ lat     : num [1:157000] 33.9 33.9 33.9 33.9 33.9 ...
 $ long    : num [1:157000] 67.7 67.7 67.7 67.7 67.7 ...
 $ type    : chr [1:157000] "confirmed" "confirmed" "confirmed" "confirmed" ...
 $ cases   : num [1:157000] 0 0 0 0 0 0 0 0 0 0 ...
 - attr(*, "problems")= tibble [45,800 × 5] (S3: tbl_df/tbl/data.frame)
  ..$ row     : int [1:45800] 37001 37002 37003 37004 37005 37006 37007 37008 37009 37010 ...
  ..$ col     : chr [1:45800] "province" "province" "province" "province" ...
  ..$ expected: chr [1:45800] "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" ...
  ..$ actual  : chr [1:45800] "Alberta" "Alberta" "Alberta" "Alberta" ...
  ..$ file    : chr [1:45800] "'coronavirus.csv'" "'coronavirus.csv'" "'coronavirus.csv'" "'coronavirus.csv'" ...
 - attr(*, "spec")=
  .. cols(
  ..   date = col_date(format = ""),
  ..   province = col_logical(),
  ..   country = col_character(),
  ..   lat = col_double(),
  ..   long = col_double(),
  ..   type = col_character(),
  ..   cases = col_double()
  .. )
Warning messages:
1: In readChar(file, size, TRUE) : truncating string with embedded nuls
2: In readChar(file, size, TRUE) : truncating string with embedded nuls
3: In readChar(file, size, TRUE) : truncating string with embedded nuls
4: In readChar(file, size, TRUE) : truncating string with embedded nuls
5: In readChar(file, size, TRUE) : truncating string with embedded nuls
6: In readChar(file, size, TRUE) : truncating string with embedded nuls
7: In readChar(file, size, TRUE) : truncating string with embedded nuls
coronavirus %>% 
  filter(date == max(date)) %>%
  select(country, type, cases) %>%
  group_by(country, type) %>%
  summarise(total_cases = sum(cases)) %>%
  pivot_wider(names_from = type,
              values_from = total_cases) %>%
  arrange(-confirmed)
`summarise()` regrouping output by 'country' (override with `.groups` argument)
coronavirus %>% 
  group_by(type, date) %>%
  summarise(total_cases = sum(cases)) %>%
  pivot_wider(names_from = type, values_from = total_cases) %>%
  arrange(date) %>%
  mutate(active = confirmed - death - recovered) %>%
  mutate(active_total = cumsum(active),
                recovered_total = cumsum(recovered),
                death_total = cumsum(death)) %>%
  plot_ly(x = ~ date,
                  y = ~ active_total,
                  name = 'Active', 
                  fillcolor = '#1f77b4',
                  type = 'scatter',
                  mode = 'none', 
                  stackgroup = 'one') %>%
  add_trace(y = ~ death_total, 
             name = "Death",
             fillcolor = '#E41317') %>%
  add_trace(y = ~recovered_total, 
            name = 'Recovered', 
            fillcolor = 'forestgreen') %>%
  layout(title = "Distribution of Covid19 Cases Worldwide",
         legend = list(x = 0.1, y = 0.9),
         yaxis = list(title = "Number of Cases"),
         xaxis = list(title = "Source: Johns Hopkins University Center for Systems Science and Engineering"))
`summarise()` regrouping output by 'type' (override with `.groups` argument)
conf_df <- coronavirus %>% 
  filter(type == "confirmed") %>%
  group_by(country) %>%
  summarise(total_cases = sum(cases)) %>%
  arrange(-total_cases) %>%
  mutate(parents = "Confirmed") %>%
  ungroup() 
`summarise()` ungrouping output (override with `.groups` argument)
  
  plot_ly(data = conf_df,
          type= "treemap",
          values = ~total_cases,
          labels= ~ country,
          parents=  ~parents,
          domain = list(column=0),
          name = "Confirmed",
          textinfo="label+value+percent parent")
ggplot(confirmed_cases, aes(x = date, y = cum_cases)) +
  geom_line(aes(x = date, y = cum_cases)) +
  ylab("Cumulative confirmed cases")

head(coronavirus)
coronavirus = tibble::rowid_to_column(coronavirus, "ID")
head(coronavirus)
# coronavirus = coronavirus %>%
#   group_by(ID) %>% 
#   mutate(cum_cases = cumsum(cases))
# coronavirus %>% head(70)
mutate(group_by(coronavirus, ID), cumcases = cumsum(cases))
df <- data.frame(id = rep(1:3, each = 5),
                 hour = rep(1:5, 3),
                 value = sample(1:15))

mutate(group_by(df,id), cumsum=cumsum(value))
plt_cum_confirmed_cases_china <- ggplot(confirmed_cases_china, aes(date, cumsum)) +
  geom_line() +
  ylab("Cumulative confirmed cases") 

# See the plot
plt_cum_confirmed_cases_china

who_events <- tribble(
  ~ date, ~ event,
  "2020-01-30", "Global health emergency declared",
  "2020-03-11", "Pandemic declared",
  "2020-02-13", "China reporting change"
) %>%
  mutate(date = as.Date(date))

# Using who_events, add vertical dashed lines with an xintercept at date
# and text at date, labeled by event, and at 100000 on the y-axis
plt_cum_confirmed_cases_china + 
  geom_vline(aes(xintercept = date), data = who_events, linetype = "dashed") +
  geom_text(aes(x = date, label = event), data = who_events, y = 1e5)

# Filter for China, from Feb 15
china_after_feb15 <- confirmed_cases_china %>%
  filter(date >= "2020-02-15")

# Using china_after_feb15, draw a line plot cum_cases vs. date
# Add a smooth trend line using linear regression, no error bars
ggplot(china_after_feb15, aes(date, cumsum)) +
  geom_line() +
  geom_smooth(method = "lm", formula = 'y ~ x', se = FALSE) +
  ylab("Cumulative confirmed cases")

not_china = coronavirus %>%
  group_by(date) %>%
  filter(country != "China", type == "confirmed")%>% 
  summarize(cases = sum(cases)) %>%
  mutate(cumsum = cumsum(cases))
`summarise()` ungrouping output (override with `.groups` argument)
not_china

# not_china %>% 
#   group_by(date) %>% 
#   summarize(cases = sum(cases)) %>% 
#   select(date, country, cases, cumsum)


glimpse(not_china)
Rows: 200
Columns: 3
$ date   <date> 2020-01-22, 2020-01-23, 2020-01-24, 2020-01-25, 2020-01-26, 2020-01-27…
$ cases  <dbl> 7, 4, 10, 7, 15, 7, 19, 10, 14, 32, 22, 10, 14, 20, 12, 12, 70, 30, 15,…
$ cumsum <dbl> 7, 11, 21, 28, 43, 50, 69, 79, 93, 125, 147, 157, 171, 191, 203, 215, 2…
not_china2 = coronavirus %>%
  group_by(date) %>%
  filter(country != "China", type == "confirmed")%>% 
  summarize(cases = sum(cases)) %>%
  mutate(cumsum = cumsum(cases))
`summarise()` ungrouping output (override with `.groups` argument)
not_china2

world_after_feb15 <- all_countries %>%
  filter(date >= "2020-02-15")


all_countries_trend_lin <- ggplot(world_after_feb15, aes(x = date, y =cumsum)) +
  geom_line() +
  geom_smooth(method = "lm", formula = 'y ~ x', se = FALSE) +
  ylab("Cumulative confirmed cases")


# See the result
all_countries_trend_lin 

# Using not_china, draw a line plot cum_cases vs. date
# Add a smooth trend line using linear regression, no error bars
plt_not_china_trend_lin <- ggplot(not_china, aes(date, cumsum)) +
  geom_line() +
  geom_smooth(method = "lm", formula = 'y ~ x', se = FALSE) +
  ylab("Cumulative confirmed cases")

# See the result
plt_not_china_trend_lin 

plt_not_china_trend_lin + 
  scale_y_log10()

Filter by top 7 countries

target = c("Brazil", "India", "Mexico", "Peru", "Russia", "South Africa", "US")
top_7countries = bycountry %>% 
  filter(country %in% target)

top_7countries
NA
ggplot(top_7countries, aes(date, total_cases))  +
There were 14 warnings (use warnings() to see them)
    geom_line(aes(group = country, color = country))+
    ylab("Cumulative confirmed cases")

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCmBgYHtyfQojIExvYWQgcGFja2FnZXMKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShwbG90bHkpCgpgYGAKCmBgYHtyfQojIFJlYWQgZGF0YXNldHMvY29uZmlybWVkX2Nhc2VzX3dvcmxkd2lkZS5jc3YgaW50byBjb25maXJtZWRfY2FzZXNfd29ybGR3aWRlCmNvcm9uYXZpcnVzIDwtIHJlYWRfY3N2KCJjb3JvbmF2aXJ1cy5jc3YiKQoKaGVhZChjb3JvbmF2aXJ1cykKc3RyKGNvcm9uYXZpcnVzKQoKIyAjIFNlZSB0aGUgcmVzdWx0CmJ5Y291bnRyeSA8LSBjb3JvbmF2aXJ1cyAlPiUgCiAgZmlsdGVyKHR5cGUgPT0gImNvbmZpcm1lZCIpICU+JQogIGdyb3VwX2J5KGNvdW50cnkpICU+JQogIHN1bW1hcmlzZSh0b3RhbF9jYXNlcyA9IHN1bShjYXNlcykpICU+JQogIGFycmFuZ2UoLXRvdGFsX2Nhc2VzKQoKYnljb3VudHJ5CgoKY29uZmlybWVkX2Nhc2VzID0gY29yb25hdmlydXMgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JQogIGZpbHRlcih0eXBlID09ICJjb25maXJtZWQiKSAlPiUKICBzdW1tYXJpemUoY2FzZXMgPSBzdW0oY2FzZXMpKSAlPiUKICBtdXRhdGUoY3Vtc3VtID0gY3Vtc3VtKGNhc2VzKSkKCiMgY29uZmlybWVkX2Nhc2VzX2NoaW5hID0gY29yb25hdmlydXMgJT4lCiMgICBncm91cF9ieShkYXRlKSAlPiUKIyAgIGZpbHRlcihjb3VudHJ5ID09ICJDaGluYSIsIHR5cGUgPT0gImNvbmZpcm1lZCIpJT4lIAojICAgc3VtbWFyaXplKGNhc2VzID0gc3VtKGNhc2VzKSkgJT4lCiMgICBtdXRhdGUoY3Vtc3VtID0gY3Vtc3VtKGNhc2VzKSkKIyBjb25maXJtZWRfY2FzZXNfY2hpbmEKCgoKKGNvbmZpcm1lZF9jYXNlcykKCgoKCgpgYGAKCgpgYGB7cn0KY29yb25hdmlydXMgJT4lIAogIGZpbHRlcihkYXRlID09IG1heChkYXRlKSkgJT4lCiAgc2VsZWN0KGNvdW50cnksIHR5cGUsIGNhc2VzKSAlPiUKICBncm91cF9ieShjb3VudHJ5LCB0eXBlKSAlPiUKICBzdW1tYXJpc2UodG90YWxfY2FzZXMgPSBzdW0oY2FzZXMpKSAlPiUKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gdHlwZSwKICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IHRvdGFsX2Nhc2VzKSAlPiUKICBhcnJhbmdlKC1jb25maXJtZWQpCmBgYAoKCmBgYHtyfQpjb3JvbmF2aXJ1cyAlPiUgCiAgZ3JvdXBfYnkodHlwZSwgZGF0ZSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX2Nhc2VzID0gc3VtKGNhc2VzKSkgJT4lCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHR5cGUsIHZhbHVlc19mcm9tID0gdG90YWxfY2FzZXMpICU+JQogIGFycmFuZ2UoZGF0ZSkgJT4lCiAgbXV0YXRlKGFjdGl2ZSA9IGNvbmZpcm1lZCAtIGRlYXRoIC0gcmVjb3ZlcmVkKSAlPiUKICBtdXRhdGUoYWN0aXZlX3RvdGFsID0gY3Vtc3VtKGFjdGl2ZSksCiAgICAgICAgICAgICAgICByZWNvdmVyZWRfdG90YWwgPSBjdW1zdW0ocmVjb3ZlcmVkKSwKICAgICAgICAgICAgICAgIGRlYXRoX3RvdGFsID0gY3Vtc3VtKGRlYXRoKSkgJT4lCiAgcGxvdF9seSh4ID0gfiBkYXRlLAogICAgICAgICAgICAgICAgICB5ID0gfiBhY3RpdmVfdG90YWwsCiAgICAgICAgICAgICAgICAgIG5hbWUgPSAnQWN0aXZlJywgCiAgICAgICAgICAgICAgICAgIGZpbGxjb2xvciA9ICcjMWY3N2I0JywKICAgICAgICAgICAgICAgICAgdHlwZSA9ICdzY2F0dGVyJywKICAgICAgICAgICAgICAgICAgbW9kZSA9ICdub25lJywgCiAgICAgICAgICAgICAgICAgIHN0YWNrZ3JvdXAgPSAnb25lJykgJT4lCiAgYWRkX3RyYWNlKHkgPSB+IGRlYXRoX3RvdGFsLCAKICAgICAgICAgICAgIG5hbWUgPSAiRGVhdGgiLAogICAgICAgICAgICAgZmlsbGNvbG9yID0gJyNFNDEzMTcnKSAlPiUKICBhZGRfdHJhY2UoeSA9IH5yZWNvdmVyZWRfdG90YWwsIAogICAgICAgICAgICBuYW1lID0gJ1JlY292ZXJlZCcsIAogICAgICAgICAgICBmaWxsY29sb3IgPSAnZm9yZXN0Z3JlZW4nKSAlPiUKICBsYXlvdXQodGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIENvdmlkMTkgQ2FzZXMgV29ybGR3aWRlIiwKICAgICAgICAgbGVnZW5kID0gbGlzdCh4ID0gMC4xLCB5ID0gMC45KSwKICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIk51bWJlciBvZiBDYXNlcyIpLAogICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiU291cmNlOiBKb2hucyBIb3BraW5zIFVuaXZlcnNpdHkgQ2VudGVyIGZvciBTeXN0ZW1zIFNjaWVuY2UgYW5kIEVuZ2luZWVyaW5nIikpCmBgYAoKYGBge3J9CmNvbmZfZGYgPC0gY29yb25hdmlydXMgJT4lIAogIGZpbHRlcih0eXBlID09ICJjb25maXJtZWQiKSAlPiUKICBncm91cF9ieShjb3VudHJ5KSAlPiUKICBzdW1tYXJpc2UodG90YWxfY2FzZXMgPSBzdW0oY2FzZXMpKSAlPiUKICBhcnJhbmdlKC10b3RhbF9jYXNlcykgJT4lCiAgbXV0YXRlKHBhcmVudHMgPSAiQ29uZmlybWVkIikgJT4lCiAgdW5ncm91cCgpIAogIAogIHBsb3RfbHkoZGF0YSA9IGNvbmZfZGYsCiAgICAgICAgICB0eXBlPSAidHJlZW1hcCIsCiAgICAgICAgICB2YWx1ZXMgPSB+dG90YWxfY2FzZXMsCiAgICAgICAgICBsYWJlbHM9IH4gY291bnRyeSwKICAgICAgICAgIHBhcmVudHM9ICB+cGFyZW50cywKICAgICAgICAgIGRvbWFpbiA9IGxpc3QoY29sdW1uPTApLAogICAgICAgICAgbmFtZSA9ICJDb25maXJtZWQiLAogICAgICAgICAgdGV4dGluZm89ImxhYmVsK3ZhbHVlK3BlcmNlbnQgcGFyZW50IikKYGBgCgpgYGB7cn0KZ2dwbG90KGNvbmZpcm1lZF9jYXNlcywgYWVzKHggPSBkYXRlLCB5ID0gY3VtX2Nhc2VzKSkgKwogIGdlb21fbGluZShhZXMoeCA9IGRhdGUsIHkgPSBjdW1fY2FzZXMpKSArCiAgeWxhYigiQ3VtdWxhdGl2ZSBjb25maXJtZWQgY2FzZXMiKQpgYGAKCmBgYHtyfQpoZWFkKGNvcm9uYXZpcnVzKQpgYGAKYGBge3J9CmNvcm9uYXZpcnVzID0gdGliYmxlOjpyb3dpZF90b19jb2x1bW4oY29yb25hdmlydXMsICJJRCIpCmhlYWQoY29yb25hdmlydXMpCmBgYAoKYGBge3J9CiMgY29yb25hdmlydXMgPSBjb3JvbmF2aXJ1cyAlPiUKIyAgIGdyb3VwX2J5KElEKSAlPiUgCiMgICBtdXRhdGUoY3VtX2Nhc2VzID0gY3Vtc3VtKGNhc2VzKSkKIyBjb3JvbmF2aXJ1cyAlPiUgaGVhZCg3MCkKCmBgYAoKCmBgYHtyfQptdXRhdGUoZ3JvdXBfYnkoY29yb25hdmlydXMsIElEKSwgY3Vtc3VtID0gY3Vtc3VtKGNhc2VzKSkKYGBgCgoKYGBge3J9CiMgZGYgPC0gZGF0YS5mcmFtZShpZCA9IHJlcCgxOjMsIGVhY2ggPSA1KSwKIyAgICAgICAgICAgICAgICAgIGhvdXIgPSByZXAoMTo1LCAzKSwKIyAgICAgICAgICAgICAgICAgIHZhbHVlID0gc2FtcGxlKDE6MTUpKQojIAojIG11dGF0ZShncm91cF9ieShkZixpZCksIGN1bXN1bT1jdW1zdW0odmFsdWUpKQpgYGAKCmBgYHtyfQpjb25maXJtZWRfY2FzZXNfY2hpbmEgPSBjb3JvbmF2aXJ1cyAlPiUKICBncm91cF9ieShkYXRlKSAlPiUKICBmaWx0ZXIoY291bnRyeSA9PSAiQ2hpbmEiLCB0eXBlID09ICJjb25maXJtZWQiKSU+JSAKICBzdW1tYXJpemUoY2FzZXMgPSBzdW0oY2FzZXMpKSAlPiUKICBtdXRhdGUoY3Vtc3VtID0gY3Vtc3VtKGNhc2VzKSkKY29uZmlybWVkX2Nhc2VzX2NoaW5hCgpjb25maXJtZWRfY2FzZXNfY2hpbmEgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpemUoY2FzZXMgPSBzdW0oY2FzZXMpKSAlPiUgCiAgc2VsZWN0KGRhdGUsIGNvdW50cnksIGNhc2VzLCBjdW1zdW0pCiAgCgpnbGltcHNlKGNvbmZpcm1lZF9jYXNlc19jaGluYSkKYGBgCgpgYGB7cn0KcGx0X2N1bV9jb25maXJtZWRfY2FzZXNfY2hpbmEgPC0gZ2dwbG90KGNvbmZpcm1lZF9jYXNlc19jaGluYSwgYWVzKGRhdGUsIGN1bXN1bSkpICsKICBnZW9tX2xpbmUoKSArCiAgeWxhYigiQ3VtdWxhdGl2ZSBjb25maXJtZWQgY2FzZXMiKSAKCiMgU2VlIHRoZSBwbG90CnBsdF9jdW1fY29uZmlybWVkX2Nhc2VzX2NoaW5hCmBgYAoKYGBge3J9Cndob19ldmVudHMgPC0gdHJpYmJsZSgKICB+IGRhdGUsIH4gZXZlbnQsCiAgIjIwMjAtMDEtMzAiLCAiR2xvYmFsIGhlYWx0aCBlbWVyZ2VuY3kgZGVjbGFyZWQiLAogICIyMDIwLTAzLTExIiwgIlBhbmRlbWljIGRlY2xhcmVkIiwKICAiMjAyMC0wMi0xMyIsICJDaGluYSByZXBvcnRpbmcgY2hhbmdlIgopICU+JQogIG11dGF0ZShkYXRlID0gYXMuRGF0ZShkYXRlKSkKCiMgVXNpbmcgd2hvX2V2ZW50cywgYWRkIHZlcnRpY2FsIGRhc2hlZCBsaW5lcyB3aXRoIGFuIHhpbnRlcmNlcHQgYXQgZGF0ZQojIGFuZCB0ZXh0IGF0IGRhdGUsIGxhYmVsZWQgYnkgZXZlbnQsIGFuZCBhdCAxMDAwMDAgb24gdGhlIHktYXhpcwpwbHRfY3VtX2NvbmZpcm1lZF9jYXNlc19jaGluYSArIAogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBkYXRlKSwgZGF0YSA9IHdob19ldmVudHMsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICBnZW9tX3RleHQoYWVzKHggPSBkYXRlLCBsYWJlbCA9IGV2ZW50KSwgZGF0YSA9IHdob19ldmVudHMsIHkgPSAxZTUpCgpgYGAKCmBgYHtyfQojIEZpbHRlciBmb3IgQ2hpbmEsIGZyb20gRmViIDE1CmNoaW5hX2FmdGVyX2ZlYjE1IDwtIGNvbmZpcm1lZF9jYXNlc19jaGluYSAlPiUKICBmaWx0ZXIoZGF0ZSA+PSAiMjAyMC0wMi0xNSIpCgojIFVzaW5nIGNoaW5hX2FmdGVyX2ZlYjE1LCBkcmF3IGEgbGluZSBwbG90IGN1bV9jYXNlcyB2cy4gZGF0ZQojIEFkZCBhIHNtb290aCB0cmVuZCBsaW5lIHVzaW5nIGxpbmVhciByZWdyZXNzaW9uLCBubyBlcnJvciBiYXJzCmdncGxvdChjaGluYV9hZnRlcl9mZWIxNSwgYWVzKGRhdGUsIGN1bXN1bSkpICsKICBnZW9tX2xpbmUoKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgZm9ybXVsYSA9ICd5IH4geCcsIHNlID0gRkFMU0UpICsKICB5bGFiKCJDdW11bGF0aXZlIGNvbmZpcm1lZCBjYXNlcyIpCmBgYAoKYGBge3J9Cm5vdF9jaGluYSA9IGNvcm9uYXZpcnVzICU+JQogIGdyb3VwX2J5KGRhdGUpICU+JQogIGZpbHRlcihjb3VudHJ5ICE9ICJDaGluYSIsIHR5cGUgPT0gImNvbmZpcm1lZCIpJT4lIAogIHN1bW1hcml6ZShjYXNlcyA9IHN1bShjYXNlcykpICU+JQogIG11dGF0ZShjdW1zdW0gPSBjdW1zdW0oY2FzZXMpKQpub3RfY2hpbmEKCiMgbm90X2NoaW5hICU+JSAKIyAgIGdyb3VwX2J5KGRhdGUpICU+JSAKIyAgIHN1bW1hcml6ZShjYXNlcyA9IHN1bShjYXNlcykpICU+JSAKIyAgIHNlbGVjdChkYXRlLCBjb3VudHJ5LCBjYXNlcywgY3Vtc3VtKQoKCmdsaW1wc2Uobm90X2NoaW5hKQpgYGAKCmBgYHtyfQpub3RfY2hpbmEyID0gY29yb25hdmlydXMgJT4lCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lCiAgZmlsdGVyKGNvdW50cnkgIT0gIkNoaW5hIiwgdHlwZSA9PSAiY29uZmlybWVkIiklPiUgCiAgc3VtbWFyaXplKGNhc2VzID0gc3VtKGNhc2VzKSkgJT4lCiAgbXV0YXRlKGN1bXN1bSA9IGN1bXN1bShjYXNlcykpCm5vdF9jaGluYTIKYGBgCgpgYGB7cn0KCndvcmxkX2FmdGVyX2ZlYjE1IDwtIGFsbF9jb3VudHJpZXMgJT4lCiAgZmlsdGVyKGRhdGUgPj0gIjIwMjAtMDItMTUiKQoKCmFsbF9jb3VudHJpZXNfdHJlbmRfbGluIDwtIGdncGxvdCh3b3JsZF9hZnRlcl9mZWIxNSwgYWVzKHggPSBkYXRlLCB5ID1jdW1zdW0pKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSAneSB+IHgnLCBzZSA9IEZBTFNFKSArCiAgeWxhYigiQ3VtdWxhdGl2ZSBjb25maXJtZWQgY2FzZXMiKQoKCiMgU2VlIHRoZSByZXN1bHQKYWxsX2NvdW50cmllc190cmVuZF9saW4gCgpgYGAKCgoKYGBge3J9CiMgVXNpbmcgbm90X2NoaW5hLCBkcmF3IGEgbGluZSBwbG90IGN1bV9jYXNlcyB2cy4gZGF0ZQojIEFkZCBhIHNtb290aCB0cmVuZCBsaW5lIHVzaW5nIGxpbmVhciByZWdyZXNzaW9uLCBubyBlcnJvciBiYXJzCnBsdF9ub3RfY2hpbmFfdHJlbmRfbGluIDwtIGdncGxvdChub3RfY2hpbmEsIGFlcyhkYXRlLCBjdW1zdW0pKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSAneSB+IHgnLCBzZSA9IEZBTFNFKSArCiAgeWxhYigiQ3VtdWxhdGl2ZSBjb25maXJtZWQgY2FzZXMiKQoKIyBTZWUgdGhlIHJlc3VsdApwbHRfbm90X2NoaW5hX3RyZW5kX2xpbiAKYGBgCgpgYGB7cn0KcGx0X25vdF9jaGluYV90cmVuZF9saW4gKyAKICBzY2FsZV95X2xvZzEwKCkKYGBgCgpgYGB7cn0KIyBHcm91cCBieSBjb3VudHJ5LCBzdW1tYXJpemUgdG8gY2FsY3VsYXRlIHRvdGFsIGNhc2VzLCBmaW5kIHRoZSB0b3AgNwpieWNvdW50cnkgPC0gY29yb25hdmlydXMgJT4lIAogIGZpbHRlcih0eXBlID09ICJjb25maXJtZWQiKSAlPiUKICBncm91cF9ieShjb3VudHJ5LCBkYXRlKSAlPiUKICBzdW1tYXJpc2UodG90YWxfY2FzZXMgPSBzdW0oY2FzZXMpKSAlPiUKICBhcnJhbmdlKC10b3RhbF9jYXNlcykKCgpieWNvdW50cnkKCgoKdG9wX2NvdW50cmllc19ieV90b3RhbF9jYXNlcyA9IGJ5Y291bnRyeSAlPiUgCiAgZ3JvdXBfYnkoY291bnRyeSkgJT4lCiAgdG9wX24oNywgdG90YWxfY2FzZXMpCgoKCgp0b3BfY291bnRyaWVzX2J5X3RvdGFsX2Nhc2VzIDwtIGJ5Y291bnRyeSAlPiUKICBncm91cF9ieShjb3VudHJ5KSAlPiUKICBzdW1tYXJpemUodG90YWxfY2FzZXMgPSBzdW0odG90YWxfY2FzZXMpKSAlPiUKICB0b3Bfbig3LCB0b3RhbF9jYXNlcykKCgoKIyBTZWUgdGhlIHJlc3VsdAp0b3BfY291bnRyaWVzX2J5X3RvdGFsX2Nhc2VzCgpgYGAKCkZpbHRlciBieSB0b3AgNyBjb3VudHJpZXMKYGBge3J9CnRhcmdldCA9IGMoIkJyYXppbCIsICJJbmRpYSIsICJNZXhpY28iLCAiUGVydSIsICJSdXNzaWEiLCAiU291dGggQWZyaWNhIiwgIlVTIikKdG9wXzdjb3VudHJpZXMgPSBieWNvdW50cnkgJT4lIAogIGZpbHRlcihjb3VudHJ5ICVpbiUgdGFyZ2V0KQoKdG9wXzdjb3VudHJpZXMKCmBgYAoKCmBgYHtyfQpnZ3Bsb3QodG9wXzdjb3VudHJpZXMsIGFlcyhkYXRlLCB0b3RhbF9jYXNlcykpICArCiAgICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gY291bnRyeSwgY29sb3IgPSBjb3VudHJ5KSkrCiAgICB5bGFiKCJDdW11bGF0aXZlIGNvbmZpcm1lZCBjYXNlcyIpCmBgYAoKCgoKCgoK